/*

Frequency of use: 1 [2] 3 4 5 MEDIUM LOW

Short:
    Mediator binds different classes together, and the individual classes 
communicate via the mediator, never directly.  In this example, Message::print() 
calls Mediator, not Printer directly.

Long:
    The mediator pattern, one of the 23 design patterns described in Design 
Patterns: Elements of Reusable Object-Oriented Software, provides a unified 
interface to a set of interfaces in a subsystem. This pattern is considered to 
be a behavioral pattern due to the way it can alter the program's running 
behavior.
Usually a program is made up of a (sometimes large) number of classes. So the 
logic and computation is distributed among these classes. However, as more 
classes are developed in a program, especially during maintenance and/or 
refactoring, the problem of communication between these classes may become more 
complex. This makes the program harder to read and maintain. Furthermore, it can 
become difficult to change the program, since any change may affect code in 
several other classes.
With the mediator pattern communication between objects is encapsulated with a 
mediator object. Objects no longer communicate directly with each other, but 
instead communicate through the mediator. This reduces the dependencies between 
communicating objects, thereby lowering the coupling.

Information sources:
 - http://calumgrant.net/patterns/index.html
 - hhttp://en.wikipedia.org/wiki/Mediator_pattern
 - http://www.dofactory.com/Patterns/Patterns.aspx
*/

#include <iostream>
#include <string>

class Printer
{
public:
	void print(const std::string & str) const
	{
		std::cout << str << std::endl;
	}
};

class Message
{
public:
	virtual ~Message() { }
	virtual void print(const class Mediator & mediator) const;
};

class Mediator
{
	const Printer & printer;
	const Message & message;
public:
	Mediator(const Printer & pr, const Message & msg) :
		printer(pr),
		message(msg) { }
	void print() const
	{
		message.print(*this);
	}
	void print(const std::string & str) const
	{
		printer.print(str);
	}
};

void Message::print(const Mediator & mediator) const
{
	mediator.print("Hello world!");
}

void hello_world(const Mediator & mediator)
{
	mediator.print();
}

int main()
{
	Printer printer;
	Message message;
	hello_world(Mediator(printer,message));
	return 0;
}

